//
// Created by wxd on 2025/8/11.
//

#pragma once

#include <iostream>

#include <vector>
#include <glm/glm.hpp>
#include <glm/trigonometric.hpp>
#include "../wrapper/log/Logger.h"
#include "../wrapper/monitor/GLDebug.hpp"
#include "../global/ChineseOutput.hpp"
#include "../global/EngineDataProperties.h"
#include "../application/app/Application.h"
#include "../glFramework/shader/Shader.h"
#include "../glFramework/constant/engine_layout.h"
#include "../glFramework/texture/Texture.h"

#include "../glFramework/utils/ResourceLoadUtils.h"

#include "../glFramework/bo/VBO.h"
#include "../glFramework/bo/VAO.h"
#include "../glFramework/bo/EBO.h"

#include "../glFramework/constant/engine_uniform.h"

#include <memory>

#include "../glFramework/geo/Triangle.h"

// note：必须../，否则无法从相对路径读取资源
inline const char* vertexPath = "../demo/shader/_015/vertex_shader.glsl";
inline const char* fragmentPath = "../demo/shader/_015/fragment_shader.glsl";
inline const char* texPath = "../demo/texture/earth.png";

inline GLenum getFormatByChannel(int channel) {
    GLenum format = 0;
    if (channel == 1) {
        format = GL_RED;
    } else if (channel == 3) {
        format = GL_RGB;
    } else if (channel == 4) {
        format = GL_RGBA;
    }
    return format;
}

inline void onResize(int w, int h) {
    glViewport(0, 0, w, h);
    std::cout << "w: " << w << " h: " << h << std::endl;
}

inline void render() {
    ChineseOutput::init();
    EngineApp.initDefaultWindowConfig();
    EngineApp.setResizeCallback(onResize);
    EngineApp.init();

    Triangle tri = Triangle(DrawType::DRAW_ARRAYS, GL_TRIANGLES);

    std::vector<glm::vec3> vertex;
    vertex.push_back(glm::vec3(0.0f, 0.5f, 0.0f));
    vertex.push_back(glm::vec3(0.3f, 0.0f, 0.0f));
    vertex.push_back(glm::vec3(-0.3f, 0.0f, 0.0f));
    tri.setPos(0, vertex);

    std::vector<glm::vec2> uvs;
    uvs.push_back(glm::vec2(0.5, 1.0));
    uvs.push_back(glm::vec2(1.0, 0.0));
    uvs.push_back(glm::vec2(0., 0.));
    tri.setUV(2, uvs);

    std::unique_ptr<Shader> shader = std::make_unique<Shader>(vertexPath, fragmentPath);
    Texture texture(texPath);
    texture.setSamplerName(EngineUniform::uTexUnit);

    while (EngineApp.update()) {
        GL_CALL(glClear(GL_COLOR_BUFFER_BIT))

        shader->bindProgram();


        shader->setUniform(EngineUniform::uW, static_cast<float>(EngineApp.getCurrentWindowWidth()));
        shader->setUniform(EngineUniform::uH, static_cast<float>(EngineApp.getCurrentWindowHeight()));

        shader->setUniform(texture.getSamplerName(), texture.getTextureUnit()); // 采样0号单元

        tri.getVAO()->bind();
        tri.draw();
        tri.getVAO()->unbind();
        shader->unbindProgram();
    }

    shader->deleteProgram();
    tri.getVAO()->destroy();
    EngineApp.destroy();
}